package com.aspire.nm.component.cmppserver.filter.coder;

import java.nio.ByteBuffer;

import javax.annotation.Resource;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
import org.springframework.stereotype.Service;

import com.aspire.nm.component.cmppserver.filter.coder.packet.CmppActiveTestPacket;
import com.aspire.nm.component.cmppserver.filter.coder.packet.CmppActiveTestRespPacket;
import com.aspire.nm.component.cmppserver.filter.coder.packet.CmppConnectPacket;
import com.aspire.nm.component.cmppserver.filter.coder.packet.CmppDeliverRespPacket;
import com.aspire.nm.component.cmppserver.filter.coder.packet.CmppPacket;
import com.aspire.nm.component.cmppserver.filter.coder.packet.CmppSubmitPacket;
import com.aspire.nm.component.cmppserver.filter.coder.packet.Packet;
import com.aspire.nm.component.cmppserver.filter.coder.packet.PacketException;
import com.aspire.nm.component.cmppserver.filter.coder.packet.Version;
import com.aspire.nm.component.cmppserver.runTime.SysRunTimeService;

@Service
public class CmppProtocolDecoder extends CumulativeProtocolDecoder {

	@Resource
	private SysRunTimeService sysRunTimeService;
	
	private CmppPacket decode(IoSession session,byte[] bytes) throws PacketException {
		CmppPacket pk = null;
		ByteBuffer buffer = ByteBuffer.wrap(bytes);
		int commandId = buffer.getInt(4);
		Version version = null;
		switch (commandId) {
		case CmppPacket.CMPP_CONNECT:
			pk = new CmppConnectPacket();
			break;
		case CmppPacket.CMPP_ACTIVE_TEST:
			pk = new CmppActiveTestPacket();
			break;
		case CmppPacket.CMPP_ACTIVE_TEST_RESP:
			pk = new CmppActiveTestRespPacket();
			pk.bizParams = new Object();
			break;
		case CmppPacket.CMPP_SUBMIT:
			version = sysRunTimeService.getUserRunTime(session).getConnection(session).getVersion();
			pk = new CmppSubmitPacket(version);
			break;
		case CmppPacket.CMPP_DELIVER_RESP:
			version = sysRunTimeService.getUserRunTime(session).getConnection(session).getVersion();
			pk = new CmppDeliverRespPacket(version);
			break;	
		default:
			pk = CmppPacket.UNKNOW_PACKET;
		}

		pk.unpack(buffer);

		return pk;
	}
	
	
	/**
	 * 返回false没有任何处理,不进filter和handler
	 * 抛出异常filter和handler中的exceptionCaught都会捕获
	 * @throws PacketException 
	 */
	@Override
	protected boolean doDecode(IoSession session, IoBuffer in,
			ProtocolDecoderOutput out) throws PacketException  {

		
		if (in.remaining() < 12 || in.getInt(in.position()) < 12
				|| in.remaining() < in.getInt(in.position())) {
			return false;
		}
		
		int totalLength = in.getInt(in.position());
		byte[] bytes = new byte[totalLength];
		in.get(bytes);
		
		Packet pk = decode(session,bytes);
		if(pk == null){
			return false;
		}else{
			out.write(pk);
			return true;
		}
	}
}
